#include "widget.h"
#include "ui_widget.h"

int Widget::count = 0;


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    init(); // 调用初始化函数，对整个布局重新初始化（不想整个构造函数太臃肿）

    // 实例化监听的服务器对象
    m_s = new QTcpServer(this);

    // 等待客户链接，当有客户端链接到达时，QtcpServer对象可以发射出一个信号(newConnection)
    connect(m_s,&QTcpServer::newConnection,this,[=](){
        QTcpSocket* _tcp = new QTcpSocket;

        _tcp = m_s->nextPendingConnection(); // 通过调用此函数获取一个Socket实例对象

        int i = count;
        count++;
        cNum++;

        m_tcp.push_back(_tcp);
        ui->online->setText("在线人数: " + QString::number(cNum));


        // 实例对象什么时候可以接收数据:(检测是否可以接收数据),就是这个实例对象发射readyread信号时
        connect(_tcp,&QTcpSocket::readyRead,this,[=](){
            QByteArray data = _tcp->readAll();
            QString all = QString::fromUtf8(data);
            QString allhead = all.mid(4); // ip + 报文,如果是文件，那就是名字+ip+报文
            QByteArray datahead = allhead.toUtf8();


            if(all.left(4) == "msg*")
            {
                // 消息转发:
                ui->record->append(datahead); // 追加进通信记录中
                for(int j = 0; j < m_tcp.size(); j++)
                {
                    if(m_tcp[j] != nullptr && j != i)
                    {
                        m_tcp[j]->write(data);
                    }
                }
            }
            else if(all.left(4) == "file")
            {
                // 此时的allhead = filename + id + txt
                QString filename;
                int namesum = 0;
                for(auto e : allhead)
                {
                    if(e == ":")
                    {
                        break;
                    }
                    filename += e;
                    namesum += 1;
                }
                QString allbody = allhead.mid(namesum + 1); // +1是因为跳过 : 符号，去除对host提取的影响

                // 文件转存:
                QString host;
                for(auto e : allbody)
                {
                    if(e == ":")
                    {
                        break;
                    }
                    host += e;
                }
                QString all2 = allbody.mid(host.size() + 1);
                QByteArray data2 = all2.toUtf8();


                // 创建发送方ip为名的文件夹用于存放文件
                QDir hostDir = QDir::currentPath() + "/AllFolder/" + host;
                QString folderPath = hostDir.absolutePath();

                if(!hostDir.exists())
                {
                    // mkpath函数: 一并连缺失的父目录一并创建
                    if (QDir().mkpath(folderPath)) {
                        ui->record->append("<font color=\"#FF0000\">" + host +
                                           " created successfully！</font> ");
                        qDebug() << "文件夹创建成功: " << folderPath;
                    } else {
                        qDebug() << "文件夹创建失败: " << folderPath;
                        ui->record->append("<font color=\"#FF0000\">" + host +
                                           " created failed！</font> ");
                    }
                }

                QFile* file = new QFile(folderPath + "/" + filename);
                file->open(QFile::Append);
                file->write(data2);
                file->close();

                // 将文字颜色设置为红色
                ui->record->append("<font color=\"#FF0000\">已成功接收 " + host +
                                   " 发送来的文件" + filename +"，请及时保存！</font> ");

                // 文件转发到其他客户端:
                for(int j = 0; j < m_tcp.size(); j++)
                {
                    if(m_tcp[j] != nullptr && j != i)
                    {
                        m_tcp[j]->write(data);
                    }
                }
            }
            else {
                // 未知就报异常
                ui->record->append("<font color=\"#FF0000\"> 未知异常！！！请及时处理！！！" + all.left(4) + "</font>");
            }
        });


        // 断开连接
        connect(_tcp, &QTcpSocket::disconnected,this,[=](){
            _tcp->close();
            _tcp->deleteLater();

            m_tcp[i] = nullptr;
            cNum--;

            ui->online->setText("在线人数: " + QString::number(cNum));
        });

    });

    // 音乐循环播放
    connect(player, &QMediaPlayer::mediaStatusChanged, this, [this](QMediaPlayer::MediaStatus status){
        if(status == QMediaPlayer::EndOfMedia)
        {
            player->play();
        }
    });
}

// 删除目录
bool removeDirRecursively(const QString &dirPath) {
    QDir dir(dirPath);

    if (!dir.exists() || !dir.isReadable()) {
        qDebug() << "Directory does not exist:" << dirPath;
        return true; // 如果目录不存在，可以认为“删除”操作是成功的
    }

    if (!dir.isReadable()) {
        qDebug() << "Directory is not readable:" << dirPath;
        return false;
    }

    QFileInfoList fileList = dir.entryInfoList(QDir::NoDotAndDotDot |
                                               QDir::AllDirs | QDir::Files);
    foreach (QFileInfo fileInfo, fileList) {
        if (fileInfo.isDir()) {
            // 递归删除子目录
            if (!removeDirRecursively(fileInfo.absoluteFilePath())) {
                return false;
            }
        } else {
            // 删除文件
            if (!QFile::remove(fileInfo.absoluteFilePath())) {
                qDebug() << "Failed to remove file:" << fileInfo.absoluteFilePath();
                return false;
            }
        }
    }

    // 删除空目录本身
    return dir.rmdir(dir.path());
}

Widget::~Widget()
{
    QString folderToDelete = QDir::currentPath() + "/AllFolder"; //当前路径 + 指定文件夹

    if (removeDirRecursively(folderToDelete)) {
        qDebug() << "Directory and its contents deleted successfully:" << folderToDelete;
    } else {
        qDebug() << "Failed to delete directory or its contents:" << folderToDelete;
    }

    delete ui;
}

void Widget::init()
{
    this->setWindowFlag(Qt::FramelessWindowHint); // 去除标题栏，重画自定义的
    ui->ChatPage->click();
    ui->PsendFile->setEnabled(false);
    player = new QMediaPlayer(this);
    printHostIPAddresses(); // 获取自己的Ipv4地址
    ui->record->setReadOnly(true);
    ui->online->setText("在线人数: " + QString::number(cNum));
    ui->port->setAlignment(Qt::AlignCenter);
    ui->portText->setAlignment(Qt::AlignCenter);

    PBs = {ui->Psendmsg, ui->Pclean, ui->PselectFile, ui->PsendFile};

    // 插入事件过滤器
    KeyFilter* k = new KeyFilter(PBs);
    ui->msg->installEventFilter(k);
    ui->filePath->installEventFilter(k);

    // 创建AllFolder
    {
        // 获取当前路径
        QDir currentDir = QDir::currentPath();

        // 定义要创建的文件夹名称
        QString folderName = "AllFolder";

        // 构造完整的文件夹路径
        QString folderPath = currentDir.absoluteFilePath(folderName);

        //QDir().mkpath(folderPath);

        // 创建文件夹
        if (QDir().mkpath(folderPath)) {
            ui->record->append("AllFolder created successfully!");
            qDebug() << "文件夹创建成功: " << folderPath;
        } else {
            qDebug() << "文件夹创建失败: " << folderPath;
            ui->record->append("<font color=\"#FF0000\"> AllFolder created failed! </font> ");
        }
    }

    // 绘制窗口:
    setAttribute(Qt::WA_TranslucentBackground); // 设置窗口透明
    // 给窗口绘制阴影效果
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0,0);
    shadowEffect->setColor("#000000"); // 黑色
    shadowEffect->setBlurRadius(20); // 圆角
    this->setGraphicsEffect(shadowEffect);

    QDir musicpathD = QDir::currentPath();
    QString musicpath = musicpathD.absolutePath();
    player->setMedia(QUrl::fromLocalFile(musicpath + "\\music.mp3")); // 任意音乐（命名为music即可）

    movie = new QMovie(musicpath + "\\kk.gif");
    ui->gifimage->setMovie(movie); // 1. 设置要显示的 GIF 动画图片
    ui->gifimage->setScaledContents(true);
    movie->start();         // 2. 启动动画
    ui->gifimage->show();

}




// 获取主机Ipv4地址
void Widget::printHostIPAddresses()
{
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    foreach (QNetworkInterface interface, interfaces) {
        if (interface.flags().testFlag(QNetworkInterface::IsUp) && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
            QList<QNetworkAddressEntry> entries = interface.addressEntries();
            foreach (QNetworkAddressEntry entry, entries) {
                // 输出所有类型的IP地址
                //qDebug() << "IP Address:" << entry.ip().toString();

                // 如果你只想要IPv4地址，可以添加以下检查
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                    //qDebug() << "IPv4 Address:" << entry.ip().toString();
                    MyHost = entry.ip().toString();
                }
            }
        }
    }
}


void Widget::on_ChatPage_clicked()
{
    ui->stackedWidget->setCurrentIndex(0);
    ui->Psendmsg->setEnabled(true);
    ui->Pclean->setEnabled(true);
    ui->PsendFile->setEnabled(false);
    ui->icon->setStyleSheet("#icon{ border-image: url(:/image/kun.jpg);}");
}
void Widget::on_filePage_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
    ui->Psendmsg->setEnabled(false);
    ui->Pclean->setEnabled(false);
    ui->PsendFile->setEnabled(true);
    ui->icon->setStyleSheet("#icon{ border-image: url(:/image/kun.jpg);}");
}
void Widget::on_Usage_clicked()
{
    ui->stackedWidget->setCurrentIndex(2);
    ui->Psendmsg->setEnabled(false);
    ui->Pclean->setEnabled(false);
    ui->PsendFile->setEnabled(false);
    ui->icon->setStyleSheet("#icon{ border-image: url(:/image/kun.jpg);}");
}
void Widget::on_morePage_clicked()
{
    ui->stackedWidget->setCurrentIndex(3);
    ui->Psendmsg->setEnabled(false);
    ui->Pclean->setEnabled(false);
    ui->PsendFile->setEnabled(false);
    ui->icon->setStyleSheet("#icon{ border-image: url(:/image/dadan.jpg);}");
}



void Widget::on_Pquit_clicked()
{
    close();
}

void Widget::on_Pmin_clicked()
{
    this->showMinimized();
}

void Widget::on_start_clicked()
{
    unsigned short port = ui->portText->text().toUShort(); // 读出端口号并转换成无符号短整型
    m_s->listen(QHostAddress::Any, port); // 启动监听，绑定IP与端口
    ui->start->setText("Started");
    ui->start->setEnabled(false); // 绑定后按钮设置为不可用

    ui->record->append(MyHost + "已启用监听服务");
}

void Widget::on_Psendmsg_clicked()
{
    if(ui->msg->toPlainText() == "") return;
    QString msg = "Server say: " + ui->msg->toPlainText(); // 将数据以纯文本的方式取出来
    QString msg2 = "msg*" + msg;

    for(int i = 0; i < m_tcp.size(); i++)
    {
        if(m_tcp[i] != nullptr)
        {
            m_tcp[i]->write(msg2.toUtf8());
        }
    }
    ui->record->append(msg); // 追加进通信记录中
    ui->msg->setText("");
}

void Widget::on_Pclean_clicked()
{
    if(ui->Pclean->text() == "C")
        ui->Pclean->setText("C?");
    else
    {
        ui->Pclean->setText("C");
        ui->record->setText("");
    }
}

void Widget::on_cancel_clicked()
{
    ui->Pclean->setText("C");
    ui->PsendFile->setText("S");
}

void Widget::on_PselectFile_clicked()
{
    ui->filePath->setStyleSheet("color: black; background-color: white;");
    ui->filePath->setText("");

    // 弹出选择文件对话框即可
    path = QFileDialog::getOpenFileName(); // 得到某个磁盘文件的绝对路径
    ui->filePath->setText(path);

}

void Widget::on_PsendFile_clicked()
{
    path = ui->filePath->text();
    if(!QFile::exists(path))
    {
        ui->filePath->setStyleSheet("color: red; background-color: white;");
        ui->filePath->setText("哎呀, 好像是个错误路径呢, 要不再试一下? (～￣▽￣)～");
        return;
    }
    if(path.right(4) != ".txt")
    {
        ui->filePath->setStyleSheet("color: red; background-color: white;");
        ui->filePath->setText("文件转发失败, 暂不支持txt格式以外的文件发送, 后续解锁, (～￣▽￣)～");
        return;
    }
    if(path != "")
    {
        QFile file(path);
        bool IsSend = false;
        file.open(QFile::ReadOnly);

        // 文件名:
        int namesum = 0;
        for(auto it = path.end() - 1; it >= path.begin(); it--)
        {
            if(*it != "/")
                namesum++;
            else
            {
                break;
            }
        }
        QString filename = path.right(namesum); // 路径的最后一个就是文件名，

        QString headers = "file" + filename + ":";

        QString host = headers + "Server:";
        QByteArray all = host.toUtf8();
        all += file.readAll();

        // 多客户端发送（过程中确认客户端是否有效）
        for(int i = 0; i < m_tcp.size(); i++)
        {
            if(m_tcp[i] != nullptr)
            {
                m_tcp[i]->write(all);
                IsSend = true;
            }
        }

        file.close();
        if(IsSend)
        {
            ui->filePath->setStyleSheet("color: red; background-color: white;");
            ui->filePath->setText("文件 " + filename + " 已发送完毕!");
        }
        else
        {
            ui->filePath->setStyleSheet("color: red; background-color: white;");
            ui->filePath->setText("文件发送失败，未有已连接的客户端!");
        }

        ui->msg->setText("");
        path = "";
    }
    else
    {
        ui->record->append("<font color=\"#FF0000\"> 文件发送失败，请检查文件路径是否正确！ </font> ");
        qDebug() << "文件发送失败 ";
    }
}



// 鼠标移动处理
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->buttons())
    {
        // 获取鼠标相对于屏幕左上角的全局坐标
        move(event->globalPos() - dragPosition);
        return;
    }
    QWidget::mouseMoveEvent(event);
}
void Widget::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->button())
    {
        // 获取鼠标相对于屏幕左上角的全局坐标
        dragPosition = event->globalPos() - geometry().topLeft();
        return;
    }
    QWidget::mousePressEvent(event);
}

// 音乐处理:
void Widget::on_play_clicked()
{
    if(player->state() == QMediaPlayer::PlayingState)
    {
        player->pause();
        ui->play->setText("►");
    }
    else
    {
        player->play();
        ui->play->setText("||");
    }
}

void Widget::on_prev_clicked()
{
    player->setPosition(player->position() - 15000);
}

void Widget::on_next_clicked()
{
    player->setPosition(player->position() + 15000);
}
